/*
 * This program is free software; you can redistribute it and/or modify
 * it under the terms of the GNU General Public License as published by
 * the Free Software Foundation; either version 2 of the License, or
 * (at your option) any later version.
 * 
 * This program is distributed in the hope that it will be useful,
 * but WITHOUT ANY WARRANTY; without even the implied warranty of
 * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
 * GNU Library General Public License for more details.
 * 
 * You should have received a copy of the GNU General Public License
 * along with this program; if not, write to the Free Software
 * Foundation, Inc., 51 Franklin Street, Fifth Floor Boston, MA 02110-1301,  USA
 */


#include "support.h"

// This is for playbin2 supported
 
GList *get_lang_list_for_type (GstElement *element, const gchar * type_name)
{
  GList *ret = NULL;
  gint num = 1;

  if (g_str_equal (type_name, "AUDIO")) {
    gint i, n;

    g_object_get (G_OBJECT (element), "n-audio", &n, NULL);
    if (n == 0)
      return NULL;

    for (i = 0; i < n; i++) {
      GstTagList *tags = NULL;

      g_signal_emit_by_name (G_OBJECT (element), "get-audio-tags",
          i, &tags);

      if (tags) {
        gchar *lc = NULL, *cd = NULL;

	gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &lc);
	gst_tag_list_get_string (tags, GST_TAG_CODEC, &lc);

        if (lc) {
	  ret = g_list_prepend (ret, lc);
	  g_free (cd);
	} else if (cd) {
	  ret = g_list_prepend (ret, cd);
	} else {
	  ret = g_list_prepend (ret, g_strdup_printf (_("Audio Track #%d"), num++));
	}
	gst_tag_list_free (tags);
      } else {
	ret = g_list_prepend (ret, g_strdup_printf (_("Audio Track #%d"), num++));
      }
    }
  } else if (g_str_equal (type_name, "TEXT")) {
    gint i, n = 0;

    g_object_get (G_OBJECT (element), "n-text", &n, NULL);
    if (n == 0)
      return NULL;

    for (i = 0; i < n; i++) {
      GstTagList *tags = NULL;

      g_signal_emit_by_name (G_OBJECT (element), "get-text-tags",
          i, &tags);

      if (tags) {
        gchar *lc = NULL, *cd = NULL;

	gst_tag_list_get_string (tags, GST_TAG_LANGUAGE_CODE, &lc);
	gst_tag_list_get_string (tags, GST_TAG_CODEC, &lc);

        if (lc) {
	  ret = g_list_prepend (ret, lc);
	  g_free (cd);
	} else if (cd) {
	  ret = g_list_prepend (ret, cd);
	} else {
	  ret = g_list_prepend (ret, g_strdup_printf (_("Subtitle #%d"), num++));
	}
	gst_tag_list_free (tags);
      } else {
	ret = g_list_prepend (ret, g_strdup_printf (_("Subtitle #%d"), num++));
      }
    }
  } else {
    g_critical ("Invalid stream type '%s'", type_name);
    return NULL;
  }

  return g_list_reverse (ret);
}

/*
GList *get_lang_list_for_type (GstElement *element, const gchar * type_name)
{
  GList *list, *l;
  GList *ret = NULL;
  gint num = 0;

  list = get_stream_info_objects_for_type (element, type_name);

  if (list == NULL)
    return NULL;

  for (l = list; l != NULL; l = l->next) {
    gchar *lc = NULL, *cd = NULL;

    g_object_get (l->data, "codec", &cd, "language-code", &lc, NULL);
    if (lc) {
      ret = g_list_prepend (ret, lc);
      g_free (cd);
    } else if (cd) {
      ret = g_list_prepend (ret, cd);
    } else {
      ret = g_list_prepend (ret, g_strdup_printf ("%s %d", type_name, num++));
    }
  }
  g_list_foreach (list, (GFunc) g_object_unref, NULL);
  g_list_free (list);

  return g_list_reverse (ret);
}
*/

GList *get_stream_info_objects_for_type (GstElement *element, const gchar * typestr)
{
  GValueArray *info_arr = NULL;
  GList *ret = NULL;
  guint i;

  if (element == NULL)
    return NULL;

  g_object_get (G_OBJECT(element), "stream-info-value-array", &info_arr, NULL);
  if (info_arr == NULL) {
    printf("info array is NULL\n");
    return NULL;
  }

  for (i = 0; i < info_arr->n_values; ++i) {
    GObject *info_obj;
    GValue *val;

    val = g_value_array_get_nth (info_arr, i);
    info_obj = g_value_get_object (val);
    if (info_obj) {
      GParamSpec *pspec;
      GEnumValue *value;
      gint type = -1;

      g_object_get (info_obj, "type", &type, NULL);
      pspec = g_object_class_find_property (G_OBJECT_GET_CLASS (info_obj), "type");
      value = g_enum_get_value (G_PARAM_SPEC_ENUM (pspec)->enum_class, type);
      if (value) {
        if (g_ascii_strcasecmp (value->value_nick, typestr) == 0 ||
            g_ascii_strcasecmp (value->value_name, typestr) == 0) {
          // printf("adding stream-info\n");
          ret = g_list_prepend (ret, g_object_ref (info_obj));
        }
      }
    }
  }
  g_value_array_free (info_arr);

  return g_list_reverse (ret);
}

gboolean clear_playlist()
{
	GList *l;
	ListItem *i;

	for(l = playlist; l != NULL; l = g_list_next(l)) {
		i = l->data;
		if (i->uri)
			g_free(i->uri);
		if (i->display)
			clutter_actor_destroy(i->display);
		if (i->tags)
			gst_tag_list_free(i->tags);
	}

	g_list_free(playlist);
	playlist = NULL;
	return TRUE;
}

gboolean add_item_to_playlist(gchar *uri)
{
	ListItem *item = g_new0(ListItem,1);

	item->uri = g_strdup(uri);
	playlist = g_list_append(playlist, item);
	request_metadata(item);
	
	return TRUE;
}

void request_metadata(ListItem *item)
{
	GstElement *fakeplaybin, *fake_video, *fake_audio;
	GstBus *fakebus;
	
	fakeplaybin = gst_element_factory_make("playbin","fakeplaybin");
	fake_video = gst_element_factory_make("fakesink","fakesink");
	fake_audio = gst_element_factory_make("fakesink","fakesink");
	g_object_set(G_OBJECT(fakeplaybin),"video-sink", fake_video, "audio-sink", fake_audio, NULL);

    fakebus = gst_element_get_bus(fakeplaybin);
	gst_bus_add_signal_watch(fakebus);
    g_signal_connect (fakebus, "message", G_CALLBACK(bus_message_callback), item);

	g_object_set(G_OBJECT(fakeplaybin),"uri", item->uri, NULL);
	gst_element_set_state (GST_ELEMENT(fakeplaybin), GST_STATE_PLAYING);
}


void cairo_rounded_rectangle(cairo_t *cr, double x0, double y0, double rect_width, double rect_height, double radius)
{
	gdouble x1,y1;

	x1=x0+rect_width;
	y1=y0+rect_height;
	if (!rect_width || !rect_height)
		return;
	if (rect_width/2<radius) {
		if (rect_height/2<radius) {
		    cairo_move_to  (cr, x0, (y0 + y1)/2);
		    cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
		    cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
		    cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
		    cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
		} else {
		    cairo_move_to  (cr, x0, y0 + radius);
		    cairo_curve_to (cr, x0 ,y0, x0, y0, (x0 + x1)/2, y0);
		    cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
		    cairo_line_to (cr, x1 , y1 - radius);
		    cairo_curve_to (cr, x1, y1, x1, y1, (x1 + x0)/2, y1);
		    cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
		}
	} else {
		if (rect_height/2<radius) {
		    cairo_move_to  (cr, x0, (y0 + y1)/2);
		    cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
		    cairo_line_to (cr, x1 - radius, y0);
		    cairo_curve_to (cr, x1, y0, x1, y0, x1, (y0 + y1)/2);
		    cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
		    cairo_line_to (cr, x0 + radius, y1);
		    cairo_curve_to (cr, x0, y1, x0, y1, x0, (y0 + y1)/2);
		} else {
		    cairo_move_to  (cr, x0, y0 + radius);
		    cairo_curve_to (cr, x0 , y0, x0 , y0, x0 + radius, y0);
		    cairo_line_to (cr, x1 - radius, y0);
		    cairo_curve_to (cr, x1, y0, x1, y0, x1, y0 + radius);
		    cairo_line_to (cr, x1 , y1 - radius);
		    cairo_curve_to (cr, x1, y1, x1, y1, x1 - radius, y1);
		    cairo_line_to (cr, x0 + radius, y1);
		    cairo_curve_to (cr, x0, y1, x0, y1, x0, y1- radius);
		}
	}
	cairo_close_path (cr);

}

void update_item_display(ListItem *item)
{
	cairo_t *cr;
	cairo_font_extents_t extents;
	gchar *tag = NULL;
	gchar *md5, *thumbnail;
	GFile *file;
	
	gdouble width, height, radius, aspect;
	gdouble text_x, text_y;
	gdouble stage_width, stage_height;

	width = 320.0;
	height = 100.0;
	radius = 15.0;
	
	
	if (item->display == NULL) {
		item->display = clutter_group_new();
		item->details = clutter_cairo_texture_new(width, height);
		//clutter_actor_show(item->display);
		// not ready to show it yet
		// clutter_actor_set_scale(item->display, 0.1, 0.1);
	    clutter_container_add_actor(CLUTTER_CONTAINER(stage),item->display); 
		clutter_container_add_actor(CLUTTER_CONTAINER(item->display),item->details);
		clutter_actor_set_reactive(item->display, TRUE);
		clutter_actor_set_opacity(item->display, 0xbb);
		g_signal_connect(item->display, "button-release-event", G_CALLBACK(on_display_button_release_event),(gpointer)item);
	}

	md5 = g_compute_checksum_for_string(G_CHECKSUM_MD5, item->uri, -1);
	thumbnail = g_strdup_printf("%s/.thumbnails/normal/%s.png",g_get_home_dir(),md5);
	if (g_file_test(thumbnail, G_FILE_TEST_EXISTS)) {
		// printf("A thumbnail exists for %s at\n%s\n",item->uri,thumbnail);
		item->thumbnail = clutter_texture_new_from_file(thumbnail, NULL);
		clutter_container_add_actor(CLUTTER_CONTAINER(item->display),item->thumbnail);
		aspect = clutter_actor_get_width(item->thumbnail) / clutter_actor_get_height(item->thumbnail);
		clutter_actor_set_size(item->thumbnail, 64.0, 64.0 / aspect);
		clutter_actor_set_position(item->thumbnail, 8.0,8.0);
		clutter_actor_set_position(item->details, 0.0,0.0);
		text_x = 72.0;
	} else {
		clutter_actor_set_position(item->details, 0.0,0.0);
		text_x = 8.0;
	}
	clutter_cairo_texture_clear(CLUTTER_CAIRO_TEXTURE(item->details));
	
	cr = clutter_cairo_texture_create(CLUTTER_CAIRO_TEXTURE(item->details));

  	/* draw on the context */
	cairo_set_source_rgb(cr, window->style->bg[0].red / 65535.0, window->style->bg[0].green / 65535.0, window->style->bg[0].blue / 65535.0);
	cairo_set_line_width(cr, 2.0);
	cairo_rounded_rectangle(cr, 0.0,0.0, width, height, radius);
	
	// cairo_rectangle(cr, 1.0, 1.0, 299.0, 199.0);
	cairo_fill_preserve(cr);
	
	cairo_stroke(cr);
	
	// cairo_set_source_rgb(cr, 0.8, 0.8, 0.8);
	cairo_set_source_rgb(cr, window->style->text[0].red / 65535.0, window->style->text[0].green / 65535.0, window->style->text[0].blue / 65535.0);

	text_y = 15.0;
	cairo_move_to(cr, text_x, text_y);
	cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_BOLD);
	cairo_set_font_size(cr, 12);
	cairo_font_extents(cr, &extents);
    gst_tag_list_get_string_index(item->tags,GST_TAG_TITLE,0,&tag);
	if (!tag) {
		file = g_file_new_for_uri(item->uri);
		tag = g_file_get_basename(file);
		g_object_unref(file);
	}
	cairo_show_text(cr, tag);

	text_y += extents.height; 
	cairo_move_to(cr, text_x, text_y);
	cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_ITALIC, CAIRO_FONT_WEIGHT_NORMAL);
	cairo_set_font_size(cr, 10);
	cairo_font_extents(cr, &extents);
	g_free(tag);
	tag = NULL;
    gst_tag_list_get_string_index(item->tags,GST_TAG_ARTIST,0,&tag);
	cairo_show_text(cr, tag);

	text_y += extents.height; 
	cairo_move_to(cr, text_x, text_y);
	cairo_select_font_face(cr, "Sans", CAIRO_FONT_SLANT_NORMAL, CAIRO_FONT_WEIGHT_NORMAL);
	cairo_set_font_size(cr, 10);
	cairo_font_extents(cr, &extents);
	g_free(tag);
	tag = NULL;
    gst_tag_list_get_string_index(item->tags,GST_TAG_ALBUM,0,&tag);
	cairo_show_text(cr, tag);
	g_free(tag);
	
  	cairo_destroy (cr);

	stage_width = clutter_actor_get_width(stage);
	stage_height = clutter_actor_get_height(stage);
	clutter_actor_set_position(item->display, 10.0,10.0);
	clutter_actor_lower(item->display,control_group);
	clutter_actor_hide(item->display);
	//clutter_actor_animate(item->display, CLUTTER_LINEAR, 100, "scale-x", 1.0, "scale-y", 1.0, NULL);

}